/*
 * @Author: moeWang
 * @Date: 2021-09-08 15:24:25
 * @LastEditTime: 2021-09-10 13:58:24
 * @LastEditors: moeWang
 * @Description: 中介者模式
 * @FilePath: \front-end-design-mode\code\Mediator.js
 */

// 玩家Player对象
function Player(name, teamColor) {
    this.name = name
    this.teamColor = teamColor
    this.state = 'alive'
}
Player.prototype.win = function () {
    console.log(this.name + 'won');
}

Player.prototype.lose = function () {
    console.log(this.name + 'lose');
}

Player.prototype.die = function () {
    this.state = 'dead'
    playerDirector.receiveMessage('playerDead', this) // 给中介者发消息 玩家死亡
}

Player.prototype.remove = function () {
    playerDirector.receiveMessage('removePlayer', this)
}

Player.prototype.changeTeam = function (color) {
    playerDirector.receiveMessage('changeTeam', this, color)
}

// 创建玩家工厂函数
var PlayerFactory = function (name, teamColor) {
    var newPlayer = new Player(name, teamColor)
    playerDirector.receiveMessage('addPlayer', newPlayer)
    return newPlayer
}

// 实现中介者playerDirector
/* 
    playerDirector开放一个对外暴露的接口receiveMessage，负责接收player对象发送的消息。
    player发送消息时将自身this传给其，以便识别消息来自于哪个玩家对象。
 */

var playerDirector = (function () {
    var players = {} // 保存所有玩家
    var operations = {} // 中介者可以执行的操作

    operations.addPlayer = function (player) {
        var teamColor = player.teamColor
        players[teamColor] = players[teamColor] || []
        players[teamColor].push(player)
    }

    operations.removePlayer = function (player) {
        var teamColor = player.teamColor
        var teamPlayers = players[teamColor] || []
        for (var i = teamPlayers.length - 1; i >= 0; i--) {
            if (teamPlayers[i] === player) {
                teamPlayers.splice(i, 1)
            }
        }
    }

    operations.changeTeam = function (player, newTeamColor) {
        operations.removePlayer(player)
        player.teamColor = newTeamColor
        console.log(player);
        operations.addPlayer(player)
    }

    operations.playerDead = function (player) {
        var teamColor = player.teamColor
        var teamPlayers = players[teamColor]
        var all_dead = true
        for (var i = 0, player; player = teamPlayers[i++];) {
            if (player.state !== 'dead') {
                all_dead = false
                break
            }
        }

        if (all_dead) {
            for (var i = 0, player; player = teamPlayers[i++];) {
                player.lose()
            }

            for (var color in players) {
                if (color !== teamColor) {
                    var teamPlayers = players[color]
                    for (var i = 0, player; player = teamPlayers[i++];) {
                        player.win()
                    }
                }
            }
        }
    }

    var receiveMessage = function () {
        var message = Array.prototype.shift.call(arguments)
        operations[message].apply(this, arguments)
    }

    return {
        receiveMessage,
        players
    }
})()


// 测试
var red1 = PlayerFactory('red1', 'red')
var red2 = PlayerFactory('red2', 'red')
var red3 = PlayerFactory('red3', 'red')
var red4 = PlayerFactory('red4', 'red')

var blue1 = PlayerFactory('blue1', 'blue')
var blue2 = PlayerFactory('blue2', 'blue')
var blue3 = PlayerFactory('blue3', 'blue')
var blue4 = PlayerFactory('blue4', 'blue')

red1.die()
blue1.remove()
blue4.die()
red4.die()
red2.changeTeam('blue')
red3.die()